/**
 * 中国象棋移动规则
 */

import { PIECE_TYPES, COLORS } from '../constants/pieces.js';
import { 
  isValidPosition, 
  isInPalace, 
  isElephantInBounds,
  DIRECTIONS 
} from '../constants/positions.js';
import { 
  isPathClear, 
  countPiecesInPath, 
  getManhattanDistance 
} from '../engine/BoardUtils.js';

/**
 * 帅/将的移动规则
 */
function kingMoveRule(from, to, board, piece) {
  const { row: fromRow, col: fromCol } = from;
  const { row: toRow, col: toCol } = to;

  // 必须在九宫格内
  if (!isInPalace(toRow, toCol, piece.color)) {
    return false;
  }

  // 只能移动一格
  const distance = getManhattanDistance(from, to);
  if (distance !== 1) {
    return false;
  }

  // 特殊规则：将帅不能照面
  // 如果目标位置与对方将帅在同一列，检查中间是否有棋子
  const opponentKingName = piece.color === COLORS.RED ? '將' : '帥';
  
  for (let row = 0; row < 10; row++) {
    for (let col = 0; col < 9; col++) {
      const otherPiece = board[row][col];
      if (otherPiece && otherPiece.name === opponentKingName) {
        // 如果移动后两个王在同一列
        if (toCol === col) {
          // 检查中间是否有其他棋子
          const minRow = Math.min(toRow, row);
          const maxRow = Math.max(toRow, row);
          let hasBlocker = false;
          
          for (let r = minRow + 1; r < maxRow; r++) {
            if (board[r][col] !== null) {
              hasBlocker = true;
              break;
            }
          }
          
          if (!hasBlocker) {
            return false; // 将帅照面，移动无效
          }
        }
        break;
      }
    }
  }

  return true;
}

/**
 * 仕/士的移动规则
 */
function advisorMoveRule(from, to, board, piece) {
  const { row: fromRow, col: fromCol } = from;
  const { row: toRow, col: toCol } = to;

  // 必须在九宫格内
  if (!isInPalace(toRow, toCol, piece.color)) {
    return false;
  }

  // 只能斜向移动一格
  const rowDiff = Math.abs(toRow - fromRow);
  const colDiff = Math.abs(toCol - fromCol);
  
  return rowDiff === 1 && colDiff === 1;
}

/**
 * 相/象的移动规则
 */
function elephantMoveRule(from, to, board, piece) {
  const { row: fromRow, col: fromCol } = from;
  const { row: toRow, col: toCol } = to;

  // 不能过河
  if (!isElephantInBounds(toRow, piece.color)) {
    return false;
  }

  // 必须田字形移动
  const rowDiff = Math.abs(toRow - fromRow);
  const colDiff = Math.abs(toCol - fromCol);
  
  if (rowDiff !== 2 || colDiff !== 2) {
    return false;
  }

  // 检查象眼是否被堵
  const eyeRow = fromRow + (toRow - fromRow) / 2;
  const eyeCol = fromCol + (toCol - fromCol) / 2;
  
  return board[eyeRow][eyeCol] === null;
}

/**
 * 车的移动规则
 */
function rookMoveRule(from, to, board, piece) {
  const { row: fromRow, col: fromCol } = from;
  const { row: toRow, col: toCol } = to;

  // 必须直线移动
  if (fromRow !== toRow && fromCol !== toCol) {
    return false;
  }

  // 路径必须畅通
  return isPathClear(from, to, board);
}

/**
 * 马的移动规则
 */
function knightMoveRule(from, to, board, piece) {
  const { row: fromRow, col: fromCol } = from;
  const { row: toRow, col: toCol } = to;

  const rowDiff = Math.abs(toRow - fromRow);
  const colDiff = Math.abs(toCol - fromCol);

  // 必须日字形移动
  if (!((rowDiff === 2 && colDiff === 1) || (rowDiff === 1 && colDiff === 2))) {
    return false;
  }

  // 检查马腿是否被堵
  let legRow, legCol;
  
  if (rowDiff === 2) {
    // 竖向移动，马腿在中间行
    legRow = fromRow + (toRow > fromRow ? 1 : -1);
    legCol = fromCol;
  } else {
    // 横向移动，马腿在中间列
    legRow = fromRow;
    legCol = fromCol + (toCol > fromCol ? 1 : -1);
  }

  return board[legRow][legCol] === null;
}

/**
 * 炮的移动规则
 */
function cannonMoveRule(from, to, board, piece) {
  const { row: fromRow, col: fromCol } = from;
  const { row: toRow, col: toCol } = to;

  // 必须直线移动
  if (fromRow !== toRow && fromCol !== toCol) {
    return false;
  }

  const targetPiece = board[toRow][toCol];
  const pieceCount = countPiecesInPath(from, to, board);

  if (targetPiece === null) {
    // 移动时，路径必须畅通
    return pieceCount === 0;
  } else {
    // 吃子时，路径中必须有且仅有一个棋子作为炮架
    return pieceCount === 1;
  }
}

/**
 * 兵/卒的移动规则
 */
function pawnMoveRule(from, to, board, piece) {
  const { row: fromRow, col: fromCol } = from;
  const { row: toRow, col: toCol } = to;

  const rowDiff = toRow - fromRow;
  const colDiff = Math.abs(toCol - fromCol);

  // 只能移动一格
  if (getManhattanDistance(from, to) !== 1) {
    return false;
  }

  if (piece.color === COLORS.RED) {
    // 红兵：起始在第6行(index=6)，向前是rowDiff=-1，过河后可左右
    if (fromRow >= 5) {
      // 未过河，只能向前
      return rowDiff === -1 && colDiff === 0;
    } else {
      // 已过河，可以向前或左右移动
      return (rowDiff === -1 && colDiff === 0) || (rowDiff === 0 && colDiff === 1);
    }
  } else {
    // 黑卒：起始在第3行(index=3)，向前是rowDiff=1，过河后可左右  
    if (fromRow <= 4) {
      // 未过河，只能向前
      return rowDiff === 1 && colDiff === 0;
    } else {
      // 已过河，可以向前或左右移动
      return (rowDiff === 1 && colDiff === 0) || (rowDiff === 0 && colDiff === 1);
    }
  }
}

/**
 * 移动规则映射表
 */
export const moveRules = {
  [PIECE_TYPES.KING]: kingMoveRule,
  [PIECE_TYPES.ADVISOR]: advisorMoveRule,
  [PIECE_TYPES.ELEPHANT]: elephantMoveRule,
  [PIECE_TYPES.ROOK]: rookMoveRule,
  [PIECE_TYPES.KNIGHT]: knightMoveRule,
  [PIECE_TYPES.CANNON]: cannonMoveRule,
  [PIECE_TYPES.PAWN]: pawnMoveRule
};

/**
 * 检查移动是否符合棋子的基本规则
 */
export function isValidPieceMove(from, to, board) {
  // 检查位置有效性
  if (!isValidPosition(to.row, to.col)) {
    return false;
  }

  const piece = board[from.row][from.col];
  if (!piece) {
    return false;
  }

  const targetPiece = board[to.row][to.col];
  
  // 不能吃自己的棋子
  if (targetPiece && targetPiece.color === piece.color) {
    return false;
  }

  // 不能原地不动
  if (from.row === to.row && from.col === to.col) {
    return false;
  }

  // 检查具体棋子的移动规则
  const ruleFunction = moveRules[piece.type];
  if (!ruleFunction) {
    return false;
  }

  return ruleFunction(from, to, board, piece);
}

/**
 * 获取指定棋子的所有合法移动
 */
export function getPossibleMoves(position, board) {
  const { row, col } = position;
  const piece = board[row][col];
  
  if (!piece) {
    return [];
  }

  const moves = [];

  // 遍历棋盘上的所有位置
  for (let toRow = 0; toRow < 10; toRow++) {
    for (let toCol = 0; toCol < 9; toCol++) {
      const to = { row: toRow, col: toCol };
      
      if (isValidPieceMove(position, to, board)) {
        moves.push(to);
      }
    }
  }

  return moves;
}

/**
 * 获取指定颜色的所有可能移动
 */
export function getAllPossibleMoves(board, color) {
  const allMoves = [];

  for (let row = 0; row < 10; row++) {
    for (let col = 0; col < 9; col++) {
      const piece = board[row][col];
      if (piece && piece.color === color) {
        const from = { row, col };
        const moves = getPossibleMoves(from, board);
        
        for (const to of moves) {
          allMoves.push({ from, to, piece });
        }
      }
    }
  }

  return allMoves;
}
